"report. Then try booting with the 'noapic' option");
}
-#define NR_IOAPIC_BIOSIDS 256
-static u8 ioapic_biosid_to_apic_enum[NR_IOAPIC_BIOSIDS];
-static void store_ioapic_biosid_mapping(void)
-{
- u8 apic;
- memset(ioapic_biosid_to_apic_enum, ~0, NR_IOAPIC_BIOSIDS);
- for ( apic = 0; apic < nr_ioapics; apic++ )
- ioapic_biosid_to_apic_enum[mp_ioapics[apic].mpc_apicid] = apic;
-}
-
/*
*
* IRQ's that are handled by the PIC in the MPS IOAPIC case.
void __init setup_IO_APIC(void)
{
- store_ioapic_biosid_mapping();
-
enable_IO_APIC();
if (acpi_ioapic)
#endif /*CONFIG_ACPI_BOOT*/
+static int ioapic_physbase_to_id(unsigned long physbase)
+{
+ int apic;
+ for ( apic = 0; apic < nr_ioapics; apic++ )
+ if ( mp_ioapics[apic].mpc_apicaddr == physbase )
+ return apic;
+ return -EINVAL;
+}
-int ioapic_guest_read(int apicid, int address, u32 *pval)
+int ioapic_guest_read(unsigned long physbase, unsigned int reg, u32 *pval)
{
- u32 val;
- int apicenum;
- union IO_APIC_reg_00 reg_00;
+ int apic;
unsigned long flags;
- if ( (apicid >= NR_IOAPIC_BIOSIDS) ||
- ((apicenum = ioapic_biosid_to_apic_enum[apicid]) >= nr_ioapics) )
- return -EINVAL;
+ if ( (apic = ioapic_physbase_to_id(physbase)) < 0 )
+ return apic;
spin_lock_irqsave(&ioapic_lock, flags);
- val = io_apic_read(apicenum, address);
+ *pval = io_apic_read(apic, reg);
spin_unlock_irqrestore(&ioapic_lock, flags);
- /* Rewrite APIC ID to what the BIOS originally specified. */
- if ( address == 0 )
- {
- reg_00.raw = val;
- reg_00.bits.ID = apicid;
- val = reg_00.raw;
- }
-
- *pval = val;
return 0;
}
-int ioapic_guest_write(int apicid, int address, u32 val)
+int ioapic_guest_write(unsigned long physbase, unsigned int reg, u32 val)
{
- int apicenum, pin, irq;
+ int apic, pin, irq;
struct IO_APIC_route_entry rte = { 0 };
struct irq_pin_list *entry;
unsigned long flags;
- if ( (apicid >= NR_IOAPIC_BIOSIDS) ||
- ((apicenum = ioapic_biosid_to_apic_enum[apicid]) >= nr_ioapics) )
- return -EINVAL;
+ if ( (apic = ioapic_physbase_to_id(physbase)) < 0 )
+ return apic;
/* Only write to the first half of a route entry. */
- if ( (address < 0x10) || (address & 1) )
+ if ( (reg < 0x10) || (reg & 1) )
return 0;
- pin = (address - 0x10) >> 1;
+ pin = (reg - 0x10) >> 1;
*(u32 *)&rte = val;
rte.dest.logical.logical_dest = cpu_mask_to_apicid(TARGET_CPUS);
if ( rte.delivery_mode > dest_LowestPrio )
{
printk("ERROR: Attempt to write weird IOAPIC destination mode!\n");
- printk(" APIC=%d/%d, lo-reg=%x\n", apicid, pin, val);
+ printk(" APIC=%d/%d, lo-reg=%x\n", apic, pin, val);
return -EINVAL;
}
/* Record the pin<->irq mapping. */
for ( entry = &irq_2_pin[irq]; ; entry = &irq_2_pin[entry->next] )
{
- if ( (entry->apic == apicenum) && (entry->pin == pin) )
+ if ( (entry->apic == apic) && (entry->pin == pin) )
break;
if ( !entry->next )
{
- add_pin_to_irq(irq, apicenum, pin);
+ add_pin_to_irq(irq, apic, pin);
break;
}
}
}
spin_lock_irqsave(&ioapic_lock, flags);
- io_apic_write(apicenum, 0x10 + 2 * pin, *(((int *)&rte) + 0));
- io_apic_write(apicenum, 0x11 + 2 * pin, *(((int *)&rte) + 1));
+ io_apic_write(apic, 0x10 + 2 * pin, *(((int *)&rte) + 0));
+ io_apic_write(apic, 0x11 + 2 * pin, *(((int *)&rte) + 1));
spin_unlock_irqrestore(&ioapic_lock, flags);
return 0;
#include <public/xen.h>
#include <public/physdev.h>
-extern int ioapic_guest_read(int apicid, int address, u32 *pval);
-extern int ioapic_guest_write(int apicid, int address, u32 pval);
+extern int
+ioapic_guest_read(
+ unsigned long physbase, unsigned int reg, u32 *pval);
+extern int
+ioapic_guest_write(
+ unsigned long physbase, unsigned int reg, u32 pval);
/*
* Demuxing hypercall.
if ( !IS_PRIV(current->domain) )
break;
ret = ioapic_guest_read(
- op.u.apic_op.apic, op.u.apic_op.offset, &op.u.apic_op.value);
+ op.u.apic_op.apic_physbase,
+ op.u.apic_op.reg,
+ &op.u.apic_op.value);
break;
case PHYSDEVOP_APIC_WRITE:
if ( !IS_PRIV(current->domain) )
break;
ret = ioapic_guest_write(
- op.u.apic_op.apic, op.u.apic_op.offset, op.u.apic_op.value);
+ op.u.apic_op.apic_physbase,
+ op.u.apic_op.reg,
+ op.u.apic_op.value);
break;
case PHYSDEVOP_ASSIGN_VECTOR: